#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "include/client.h"
#include "include/common.h"
#define LARGE_FILE_THRESHOLD 1024 * 1024 * 1024

// 连接服务器
int connect_server(const char *ip, short int port)
{
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(sockFd, -1, "socket");
    struct sockaddr_in addr = {0};
    struct in_addr ipAddr;
    inet_aton(ip, &ipAddr);
    int portNet = htons(port);
    addr.sin_family = AF_INET;
    addr.sin_addr = ipAddr;
    addr.sin_port = portNet;

    int connectRet = connect(sockFd, (struct sockaddr *)&addr, sizeof(addr));
    ERROR_CHECK(connectRet, -1, "connect");

    return sockFd;
}
// 登录操作
int login(int sockFd)
{
    int flag_login;
    char username[64] = {0}, password[64] = {0}, buf[MAX_BUF];
    recv(sockFd, buf, sizeof(buf) - 1, 0);
    printf("%s", buf);
    fflush(stdout);
    fgets(username, sizeof(username), stdin);
    username[strlen(username) - 1] = 0;
    send(sockFd, username, strlen(username), 0);
    fflush(stdin);
    recv(sockFd, buf, sizeof(buf) - 1, 0);
    // 检查是否是注册提示
    if (strncmp(buf, "User not found.", 15) == 0) {
        printf("%s", buf);
        fflush(stdout);
        char regbuf[16] = {0};
        fgets(regbuf, sizeof(regbuf), stdin);
        regbuf[strcspn(regbuf, "\n")] = 0;
        send(sockFd, regbuf, strlen(regbuf), 0);
        if (strncmp(regbuf, "register", 8) == 0) {
            recv(sockFd, buf, sizeof(buf) - 1, 0); // Set password:
            printf("%s", buf);
            fflush(stdout);
            fgets(password, sizeof(password), stdin);
            password[strlen(password) - 1] = 0;
            send(sockFd, password, strlen(password), 0);
            recv(sockFd, &flag_login, sizeof(flag_login), 0);
            if (flag_login == 1) {
                printf("注册成功，已登录\n");
                return 1;
            } else {
                printf("注册失败\n");
                return 0;
            }
        } else {
            recv(sockFd, &flag_login, sizeof(flag_login), 0);
            printf("登录失败\n");
            return 0;
        }
    }
    // 否则为正常登录流程
    printf("%s", buf);
    fflush(stdout);
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    fflush(stdin);
    send(sockFd, password, strlen(password), 0);
    recv(sockFd, &flag_login, sizeof(flag_login), 0);
    if (flag_login == 1)
    {
        printf("登录成功\n");
        return 1;
    }
    else
    {
        printf("登录失败\n");
        return 0;
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s <server_ip> <port>\n", argv[0]);
        exit(1);
    }
    char buf[MAX_BUF];
    long long file_size;
    int sockFd = connect_server(argv[1], atoi(argv[2]));
    int res = login(sockFd);
    // printf("res = %d\n",res);
    if (res == 0)
    {
        printf("认证失败，连接断开。\n");
        close(sockFd);
        return 1;
    }
    else
    {
        char response[MAX_BUF*2];

        while (1)
        {
            char cmdline[MAX_CMD];
            int ret = 0;
            printf("commond>");
            fflush(stdin);
            int flag;
            char *back;
            if ((back = fgets(cmdline, sizeof(cmdline), stdin)) == NULL)
            {
                continue;
            }
            cmdline[strlen(cmdline) - 1] = 0;
            // 帮助命令
            if (strcmp(cmdline, "help") == 0)
            {
                // help();
                continue;
            }
            // 字符传唤命令枚举
            command cmd;
            parse_command(cmdline, &cmd);
            send(sockFd, &cmd, sizeof(cmd), 0);
            switch (cmd.type)
            {
            case CMD_PUTS:
                // 文档功能：上传文件
                
                continue;
            case CMD_GETS:
                
               
                continue;
            case CMD_CD:

                continue;
            case CMD_PWD:

                continue;
            case CMD_REMOVE:
            case CMD_MKDIR:
            case CMD_RMDIR:

                continue;
            case CMD_LS:

                continue;
            case CMD_QUIT:
            
                break;

            default:

                continue;
            }
        }
    }
}